{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(47, 3) <class 'numpy.ndarray'>\n",
      "(47, 1) <class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "def normalize_feature(df):\n",
    "    return df.apply(lambda column: (column - column.mean()) / column.std())\n",
    "\n",
    "df = normalize_feature(pd.read_csv('data1.csv', names=['square', 'bedrooms', 'price']))\n",
    "ones = pd.DataFrame({'ones': np.ones(len(df))})\n",
    "df = pd.concat([ones, df], axis=1)\n",
    "\n",
    "X_data = np.array(df[df.columns[0:3]])\n",
    "Y_data = np.array(df[df.columns[-1]]).reshape(len(df), 1)\n",
    "\n",
    "print(X_data.shape, type(X_data))\n",
    "print(Y_data.shape, type(Y_data))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:523: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:524: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "D:\\ProgramData\\Anaconda3\\envs\\tensorflow112\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:532: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "alpha = 0.01 # 学习率 alpha\n",
    "epoch = 500 # 训练全量数据集的轮数\n",
    "\n",
    "with tf.name_scope('input'):\n",
    "    # 输入 X，形状[47, 3]\n",
    "    X = tf.placeholder(tf.float32, X_data.shape, name='X')\n",
    "    # 输出 y，形状[47, 1]\n",
    "    y = tf.placeholder(tf.float32, Y_data.shape, name='y')\n",
    "\n",
    "with tf.name_scope('hypothesis'):\n",
    "    # 权重变量 W，形状[3,1]\n",
    "    W = tf.get_variable(\"weights\",\n",
    "                        (X_data.shape[1], 1),\n",
    "                        initializer=tf.constant_initializer())\n",
    "    # 假设函数 h(x) = w0*x0+w1*x1+w2*x2, 其中x0恒为1\n",
    "    # 推理值 y_pred  形状[47,1]\n",
    "    y_pred = tf.matmul(X, W, name='y_pred')\n",
    "\n",
    "with tf.name_scope('loss'):\n",
    "    # 损失函数采用最小二乘法，y_pred - y 是形如[47, 1]的向量。\n",
    "    # tf.matmul(a,b,transpose_a=True) 表示：矩阵a的转置乘矩阵b，即 [1,47] X [47,1]\n",
    "    # 损失函数操作 loss\n",
    "    loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred - y), transpose_a=True)\n",
    "with tf.name_scope('train'):\n",
    "    # 随机梯度下降优化器 opt\n",
    "    train_op = tf.train.GradientDescentOptimizer(learning_rate=alpha).minimize(loss_op)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 10 \t Loss=0.4116 \t Model: y = 0.0791x1 + 0.03948x2 + 3.353e-10\n",
      "Epoch 20 \t Loss=0.353 \t Model: y = 0.1489x1 + 0.07135x2 + -5.588e-11\n",
      "Epoch 30 \t Loss=0.3087 \t Model: y = 0.2107x1 + 0.09676x2 + 3.912e-10\n",
      "Epoch 40 \t Loss=0.2748 \t Model: y = 0.2655x1 + 0.1167x2 + -1.863e-11\n",
      "Epoch 50 \t Loss=0.2489 \t Model: y = 0.3142x1 + 0.1321x2 + 1.77e-10\n",
      "Epoch 60 \t Loss=0.2288 \t Model: y = 0.3576x1 + 0.1436x2 + -4.47e-10\n",
      "Epoch 70 \t Loss=0.2131 \t Model: y = 0.3965x1 + 0.1519x2 + -8.103e-10\n",
      "Epoch 80 \t Loss=0.2007 \t Model: y = 0.4313x1 + 0.1574x2 + -6.985e-10\n",
      "Epoch 90 \t Loss=0.1908 \t Model: y = 0.4626x1 + 0.1607x2 + -4.936e-10\n",
      "Epoch 100 \t Loss=0.1828 \t Model: y = 0.4909x1 + 0.1621x2 + -6.147e-10\n",
      "Epoch 110 \t Loss=0.1763 \t Model: y = 0.5165x1 + 0.162x2 + -7.87e-10\n",
      "Epoch 120 \t Loss=0.1709 \t Model: y = 0.5397x1 + 0.1606x2 + -5.821e-10\n",
      "Epoch 130 \t Loss=0.1664 \t Model: y = 0.5609x1 + 0.1581x2 + -9.08e-10\n",
      "Epoch 140 \t Loss=0.1625 \t Model: y = 0.5802x1 + 0.1549x2 + -9.965e-10\n",
      "Epoch 150 \t Loss=0.1592 \t Model: y = 0.5979x1 + 0.1509x2 + -9.756e-10\n",
      "Epoch 160 \t Loss=0.1564 \t Model: y = 0.6142x1 + 0.1465x2 + -4.144e-10\n",
      "Epoch 170 \t Loss=0.1539 \t Model: y = 0.6292x1 + 0.1416x2 + -1.001e-10\n",
      "Epoch 180 \t Loss=0.1518 \t Model: y = 0.643x1 + 0.1364x2 + -3.236e-10\n",
      "Epoch 190 \t Loss=0.1498 \t Model: y = 0.6559x1 + 0.131x2 + -6.286e-11\n",
      "Epoch 200 \t Loss=0.1481 \t Model: y = 0.6678x1 + 0.1255x2 + 2.119e-10\n",
      "Epoch 210 \t Loss=0.1466 \t Model: y = 0.6789x1 + 0.1199x2 + -1.956e-10\n",
      "Epoch 220 \t Loss=0.1452 \t Model: y = 0.6892x1 + 0.1142x2 + -1.758e-10\n",
      "Epoch 230 \t Loss=0.1439 \t Model: y = 0.6989x1 + 0.1085x2 + -4.307e-11\n",
      "Epoch 240 \t Loss=0.1428 \t Model: y = 0.708x1 + 0.1029x2 + 3.376e-10\n",
      "Epoch 250 \t Loss=0.1418 \t Model: y = 0.7165x1 + 0.09736x2 + 2.841e-10\n",
      "Epoch 260 \t Loss=0.1408 \t Model: y = 0.7245x1 + 0.09189x2 + 3.295e-10\n",
      "Epoch 270 \t Loss=0.14 \t Model: y = 0.732x1 + 0.08653x2 + -8.033e-11\n",
      "Epoch 280 \t Loss=0.1392 \t Model: y = 0.7391x1 + 0.08128x2 + 1.141e-10\n",
      "Epoch 290 \t Loss=0.1385 \t Model: y = 0.7458x1 + 0.07616x2 + 1.321e-10\n",
      "Epoch 300 \t Loss=0.1378 \t Model: y = 0.7522x1 + 0.07118x2 + 5.087e-10\n",
      "Epoch 310 \t Loss=0.1372 \t Model: y = 0.7582x1 + 0.06634x2 + 7.398e-10\n",
      "Epoch 320 \t Loss=0.1367 \t Model: y = 0.7639x1 + 0.06165x2 + 6.845e-10\n",
      "Epoch 330 \t Loss=0.1362 \t Model: y = 0.7693x1 + 0.0571x2 + 8.423e-10\n",
      "Epoch 340 \t Loss=0.1357 \t Model: y = 0.7744x1 + 0.0527x2 + 9.252e-10\n",
      "Epoch 350 \t Loss=0.1353 \t Model: y = 0.7793x1 + 0.04845x2 + 1.104e-09\n",
      "Epoch 360 \t Loss=0.1349 \t Model: y = 0.784x1 + 0.04435x2 + 1.145e-09\n",
      "Epoch 370 \t Loss=0.1346 \t Model: y = 0.7884x1 + 0.0404x2 + 1.631e-09\n",
      "Epoch 380 \t Loss=0.1343 \t Model: y = 0.7926x1 + 0.03658x2 + 1.446e-09\n",
      "Epoch 390 \t Loss=0.134 \t Model: y = 0.7966x1 + 0.03291x2 + 1.429e-09\n",
      "Epoch 400 \t Loss=0.1337 \t Model: y = 0.8004x1 + 0.02938x2 + 1.694e-09\n",
      "Epoch 410 \t Loss=0.1334 \t Model: y = 0.8041x1 + 0.02598x2 + 1.697e-09\n",
      "Epoch 420 \t Loss=0.1332 \t Model: y = 0.8076x1 + 0.02271x2 + 2.125e-09\n",
      "Epoch 430 \t Loss=0.133 \t Model: y = 0.8109x1 + 0.01957x2 + 2.292e-09\n",
      "Epoch 440 \t Loss=0.1328 \t Model: y = 0.8141x1 + 0.01655x2 + 2.913e-09\n",
      "Epoch 450 \t Loss=0.1326 \t Model: y = 0.8171x1 + 0.01366x2 + 3.412e-09\n",
      "Epoch 460 \t Loss=0.1325 \t Model: y = 0.82x1 + 0.01087x2 + 3.749e-09\n",
      "Epoch 470 \t Loss=0.1323 \t Model: y = 0.8228x1 + 0.008204x2 + 3.499e-09\n",
      "Epoch 480 \t Loss=0.1322 \t Model: y = 0.8254x1 + 0.005641x2 + 3.663e-09\n",
      "Epoch 490 \t Loss=0.1321 \t Model: y = 0.828x1 + 0.003183x2 + 4.2e-09\n",
      "Epoch 500 \t Loss=0.132 \t Model: y = 0.8304x1 + 0.0008239x2 + 4.138e-09\n"
     ]
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    # 初始化全局变量\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    # 创建FileWriter实例，并传入当前会话加载的数据流图\n",
    "    writer = tf.summary.FileWriter('./summary/linear-regression-1', sess.graph)\n",
    "    # 开始训练模型\n",
    "    # 因为训练集较小，所以每轮都使用全量数据训练\n",
    "    for e in range(1, epoch + 1):\n",
    "        sess.run(train_op, feed_dict={X: X_data, y: Y_data})\n",
    "        if e % 10 == 0:\n",
    "            loss, w = sess.run([loss_op, W], feed_dict={X: X_data, y: Y_data})\n",
    "            log_str = \"Epoch %d \\t Loss=%.4g \\t Model: y = %.4gx1 + %.4gx2 + %.4g\"\n",
    "            print(log_str % (e, loss, w[1], w[2], w[0]))\n",
    "\n",
    "# 关闭FileWriter的输出流\n",
    "writer.close()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "tensorflow112",
   "language": "python",
   "display_name": "tensorflow112"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}